package game.module.user.logic;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import game.HallServer;
import game.common.ItemConstants;
import game.entity.PlayingRole;
import game.lan.bean.LoginSessionBean;
import game.lan.bean.OpenLoginSessionBean;
import game.lan.cache.LoginSessionCache;
import game.logic.ServerCache;
import game.module.battleReport.dao.PlayerReportCache;
import game.module.club.logic.ClubManager;
import game.module.club.logic.ClubRoomManager;
import game.module.dabt.dao.DabtCache;
import game.module.ddz.logic.DdzDataManager;
import game.module.hall.bean.SettingBean;
import game.module.hall.dao.SettingCache;
import game.module.hall.dao.SettingDao;
import game.module.hall.logic.HallManager;
import game.module.item.bean.Item;
import game.module.item.dao.ItemCache;
import game.module.mail.dao.MailCache;
import game.module.offline.logic.PlayerOfflineManager;
import game.module.turntables.dao.TurntableCache;
import game.module.user.bean.Activity_stateBean;
import game.module.user.bean.PlayerBaseInfo;
import game.module.user.bean.PlayerBean;
import game.module.user.dao.ActivitystateCache;
import game.module.user.dao.PlayerDao;
import game.session.PlayerOnlineCacheMng;
import game.session.SessionManager;
import lion.netty4.message.GamePlayer;
import lion.netty4.message.MySendToMessage;
import lua.LuaMessageHall.PushKickOff;
import lua.LuaMessageHall.PushPlayerInfo;
import lua.LuaMessageHall.PushSettingCfg;
import lua.LuaMessageHall.PushTurntable;
import lua.LuaMessageHall.S2CEnterHall;
import sdk.zy.WeiXinOpenApi;

public class PlayerManager {

	private static Logger logger = LoggerFactory.getLogger(PlayerManager.class);

	static class SingletonHolder {
		static PlayerManager instance = new PlayerManager();
	}

	public static PlayerManager getInstance() {
		return SingletonHolder.instance;
	}

	private PlayerDao playerDao = PlayerDao.getInstance();
	private SettingDao settingDao = SettingDao.getInstance();

	private boolean cacheNewPlayer(GamePlayer gamePlayer, PlayerBean userBean) {
		// 保存玩家
		PlayingRole existHero = SessionManager.getInstance().getPlayer(userBean.getId());
		if (existHero != null) {
			logger.warn("重复登录！,id={}", userBean.getId());
			if (existHero.getGamePlayer() != null) {
				if (existHero.getGamePlayer() == gamePlayer) {
					logger.info("channel is the same!addr={}", gamePlayer.getAddress());
					Long inGameSessionId = existHero.getGamePlayer().getSessionId();
					SessionManager.getInstance().visit(inGameSessionId);
					return true;
				} else {
					Long oldSessionId = existHero.getGamePlayer().getSessionId();
					if (oldSessionId != null) {
						SessionManager.getInstance().removeLogicHero(oldSessionId);
					}
					if (existHero.isChannelActive()) {
						PushKickOff retMsg = new PushKickOff();
						existHero.writeAndFlush(retMsg.build(existHero.alloc()));
					}
					existHero.getGamePlayer().saveSessionId(null);
					ClubManager.getInstance().loginClubAddlivenessNum(existHero);
					userBean.setDownlineTime(new Date());
				}
			}
		} else {
			SessionManager.getInstance().remove(userBean.getId());
		}
		PlayingRole aHero = new PlayingRole(gamePlayer, userBean);
		Long sessionId = SessionManager.getInstance().create(aHero);
		gamePlayer.saveSessionId(sessionId);
		return true;
	}

	public boolean checkSessionIdExist(long sessionId, int uid) {
		boolean ret = false;
		LoginSessionBean lsb = LoginSessionCache.getInstance().getLoginSessionBean(sessionId);
		if (lsb != null && lsb.getUid() == uid) {
			ret = true;
		}
		return ret;
	}

	public void queryCharacterList(GamePlayer gamePlayer, LoginSessionBean loginSessionBean) throws IOException {
		List<PlayerBean> retList = playerDao.getPlayersByPlatfrom(loginSessionBean);
		MySendToMessage retMsg = new MySendToMessage(gamePlayer.alloc(), 10102);
		if (retList == null || retList.size() == 0) {
			retMsg.writeBool(false);
		} else {
			retMsg.writeBool(true);
		}
		gamePlayer.writeAndFlush(retMsg);
	}

	public void enterHall(final GamePlayer player, final LoginSessionBean loginSessionBean) {
		HallServer.executorService.execute(new Runnable() {
			@Override
			public void run() {
				// find from cache
				int serverId = 0;
				serverId = loginSessionBean.getServerId();
				String gaOpenId = getOpenId(loginSessionBean);
				PlayerBean playerBean = PlayerOnlineCacheMng.getInstance().getCache(gaOpenId, serverId);

				if (playerBean == null) {
					// find from db
					List<PlayerBean> retList = playerDao.getPlayersByPlatfrom(loginSessionBean);
					if (retList == null || retList.size() <= 0) {
						logger.info("角色不存在,创建角色,openId={}", gaOpenId);
						// 获取角色基本信息
						PlayerBaseInfo playerBaseInfo = getPlayerBaseInfo(loginSessionBean);
						if (playerBaseInfo == null) {
							S2CEnterHall retMsg = new S2CEnterHall(player.getSessionId(), 3, 0);
							player.writeAndFlush(retMsg.build(player.alloc()));
							return;
						}
						// 创建角色
						PlayerBean pb = new PlayerBean();
						pb.setAccountId(gaOpenId);
						pb.setCoins(2000);
						pb.setCreate_time(new Date());
						pb.setFang_ka(500);
						pb.setHeadimg(playerBaseInfo.getHeadimgurl());
						pb.setLevel(1);
						pb.setLevel_exp(0);
						pb.setName(playerBaseInfo.getNickname());
						pb.setSex(playerBaseInfo.getSex());
						pb.setYuan_bao(0);
						pb.setJin_dou(0L);
						pb.setClub_id(0);
						playerDao.addUser(pb);
						playerBean = pb;
					} else {
						playerBean = retList.get(0);
					}
				}
				// 账号被禁
				if (ServerCache.getInstance().isFengHao(playerBean.getId())) {
					S2CEnterHall retMsg = new S2CEnterHall(player.getSessionId(), 2, 0);
					player.writeAndFlush(retMsg.build(player.alloc()));
					return;
				}
				boolean addRet = cacheNewPlayer(player, playerBean);
				if (!addRet) {
					S2CEnterHall retMsg = new S2CEnterHall(player.getSessionId(), 1, 0);
					player.writeAndFlush(retMsg.build(player.alloc()));
					return;
				} else {
					logger.info("player enter game,id={},ipAddr={},sessionId={}", playerBean.getId(), player.getAddress(), player.getSessionId());
					loadPlayerData(playerBean.getId());
					// online time
					PlayingRole playingRole = SessionManager.getInstance().getPlayer(playerBean.getId());
					if (playingRole != null) {
						playingRole.getPlayerCacheStatus().setEnterGameTime(new Date());
					}
					// login log
					// logLogin(playerBean.getId());
					// 首次登陆
					if (playerBean.getDownlineTime() == null) {
						// GuideManager.getInstance().logNewguide(0);
					}
					// update cache
					LoginSessionCache.getInstance().removeLoginSession(loginSessionBean);
					// loadPlayerData(playerBean.getId());
					// ret msg
					int ddzOnlineSize = DdzDataManager.getInstance().getOnlineSize();

					// push 设置消息、语音
					PushSettingCfg pushSettingCfg = new PushSettingCfg();
					//
					SettingBean s = SettingCache.getInstance().getSetting(playerBean.getId());
					if (s == null) {
						pushSettingCfg.msg = 1;
						pushSettingCfg.voice = 1;
						pushSettingCfg.club_invite = 1;
					} else {
						if (s.isMsg())
							pushSettingCfg.msg = 1;
						else
							pushSettingCfg.msg = 0;

						if (s.isVoice())
							pushSettingCfg.voice = 1;
						else
							pushSettingCfg.voice = 0;

						if (s.isClubInvite())
							pushSettingCfg.club_invite = 1;
						else
							pushSettingCfg.club_invite = 0;

					}
					player.writeAndFlush(pushSettingCfg.build(player.alloc()));

					// Activity_stateBean activitybena =
					// ActivitystateCache.getInstance()
					// .getActivitystate(playerBean.getId());
					// if (activitybena == null) {
					// // 游戏状态
					// activitybena = new Activity_stateBean();
					// activitybena.setPlayerId(playerBean.getId());
					// activitybena.setTurntable_state(true);
					// activitybena.setLogin_time(new Date());
					// Activity_stateHelper.getInstance().asyncAddActivity_state(activitybena);
					// ActivitystateCache.getInstance().addActivitystate(activitybena);
					// PushTurntable push = new PushTurntable();
					// player.writeAndFlush(push.build(player.alloc()));
					// } else {
					// Date now = new Date();
					// Date last = activitybena.getLogin_time();
					// if (!DateUtils.isSameDay(now, last)) {
					// activitybena.setLogin_time(now);
					// activitybena.setTurntable_state(true);
					// }
					// if (activitybena.isTurntable_state()) {
					// PushTurntable push = new PushTurntable();
					// player.writeAndFlush(push.build(player.alloc()));
					// }
					//
					// }
					S2CEnterHall retMsg = new S2CEnterHall(player.getSessionId(), 0, ddzOnlineSize);
					// 玩家信息
					PushPlayerInfo pushPlayerInfo = new PushPlayerInfo();
					pushPlayerInfo.player_id = playerBean.getId();
					pushPlayerInfo.name = playerBean.getName();
					pushPlayerInfo.account_id = playerBean.getAccountId();
					pushPlayerInfo.sex = playerBean.getSex().shortValue();
					pushPlayerInfo.headimg = playerBean.getHeadimg();
					long jindou = playerBean.getJin_dou() == null ? 0 : playerBean.getJin_dou();
					pushPlayerInfo.yuan_bao = (int) jindou;
					pushPlayerInfo.fang_ka = playerBean.getFang_ka();
					pushPlayerInfo.club_id = playerBean.getClub_id();
					Item item = ItemCache.getInstance().getItemByPlayerIdAndItemId(playerBean.getId(), ItemConstants.CLUB_BADGE_ITEM_ID);
					pushPlayerInfo.club_badge_num = item == null ? 0 : item.getCount();
					player.write(pushPlayerInfo.build(player.alloc()));
					//
					player.writeAndFlush(retMsg.build(player.alloc()));

					// load offline
					PlayerOfflineManager.getInstance().addOrUpdatePlayerOffline(playerBean);
					// 重回房间推送
					HallManager.getInstance().checkHallRoomType(playingRole);
					ClubRoomManager.getInstance().pushClubRoom(playingRole);
				}
			}
		});
	}

	protected void loadPlayerData(Integer playerId) {
		SettingCache.getInstance().loadFromDb(playerId);
		ItemCache.getInstance().loadFromDb(playerId);
		TurntableCache.getInstance().loadFromDb(playerId);
		ActivitystateCache.getInstance().loadFromDB(playerId);
		DabtCache.getInstance().LoadFromDb(playerId);
		MailCache.getInstance().loadFromDb(playerId);
		PlayerReportCache.getInstance().loadFromDb(playerId);
	}

	protected PlayerBaseInfo getPlayerBaseInfo(LoginSessionBean loginSessionBean) {
		PlayerBaseInfo ret = null;
		if (loginSessionBean instanceof OpenLoginSessionBean) {
			OpenLoginSessionBean openLoginSession = (OpenLoginSessionBean) loginSessionBean;
			String openId = openLoginSession.getOpenId();
			String accessToken = openLoginSession.getAccessToken();
			Map<String, Object> userinfoRet = WeiXinOpenApi.getInstance().get_userinfo(accessToken, openId);
			logger.info("weixin userinfo ret={}", userinfoRet);
			if (userinfoRet.containsKey("errcode")) {
				return null;
			} else {
				int sex = (int) userinfoRet.get("sex");
				String nickname = String.valueOf(userinfoRet.get("nickname"));
				String headimgurl = String.valueOf(userinfoRet.get("headimgurl"));
				ret = new PlayerBaseInfo(sex, nickname, headimgurl);
			}
		} else {
			int sex = RandomUtils.nextInt(1, 3);
			String nickname = String.valueOf(loginSessionBean.getUid());
			String headimgurl = "";
			ret = new PlayerBaseInfo(sex, nickname, headimgurl);
		}
		return ret;
	}

	protected String getOpenId(LoginSessionBean loginSessionBean) {
		String ret = "";
		if (loginSessionBean instanceof OpenLoginSessionBean) {
			ret = ((OpenLoginSessionBean) loginSessionBean).getOpenId();
		} else {
			ret = String.valueOf(loginSessionBean.getUid());
		}
		return ret;
	}

	public static void main(String[] args) {
		Date lasttime = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String a = sdf.format(lasttime);
		System.out.println(a);
	}

}
